﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using Microsoft.Win32;
using System.Windows;
using System.Xml;
using SHomeWorkshop.LunarConcept.Controls;
using SHomeWorkshop.LunarConcept.Tools;
using SHomeWorkshop.LunarConcept.ModifingManager;
using SHomeWorkshop.LunarConcept.Widgets;
using SHomeWorkshop.LunarConcept.Widgets.Interfaces;

namespace SHomeWorkshop.LunarConcept.Commands
{
    /// <summary>
    /// 创建时间：2012年1月21日
    /// 创建者：  杨震宇
    /// 
    /// 主要用途：选定部件左对齐。
    /// ★★说明：关于自定义命令的实现，可参考“NewDocument”类的备注。
    /// </summary>
    public static class AlignWidgetsToLeftCommand
    {
        #region 构造方法=====================================================================================================

        /// <summary>
        /// ★②，修改静态构造方法名。
        /// </summary>
        static AlignWidgetsToLeftCommand()//类型构造器
        {
            //★③，修改两个字符串参数名。★④以及第三个参数的类型名。
            routedUICmd = new RoutedUICommand(
                "AlignWidgetsToLeftCommand",
                "AlignWidgetsToLeftCommand",
                typeof(AlignWidgetsToLeftCommand),//创建RoutedUICommand对象
                null);

            routedUICmd.InputGestures.Add(new KeyGesture(Key.L, ModifierKeys.Control, "Ctrl + L"));

            //如果需要挂接快捷键，请参考下面这段代码：
            //routedUICmd = new RoutedUICommand(
            //    "SaveDocumentCommand",
            //    "SaveDocumentCommand",
            //    typeof(SaveDocumentCommand),//创建RoutedUICommand对象
            //    new InputGestureCollection() 
            //    { 
            //        //★⑤，修改此处三个参数，以便挂接快捷键。
            //        new KeyGesture(Key.S,ModifierKeys.Control,"Ctrl+S")
            //    });

            cmdBinding.Command = routedUICmd;
            cmdBinding.CanExecute += new CanExecuteRoutedEventHandler(cmdBinding_CanExecute);
            cmdBinding.Executed += new ExecutedRoutedEventHandler(cmdBinding_Executed);
        }

        #endregion

        #region 字段与属性===================================================================================================

        private static CommandBinding cmdBinding = new CommandBinding();
        /// <summary>
        /// 用在主窗口CommandBindings集合中的命令绑定。
        /// 
        /// 它的Command是RoutedUICommand。
        /// ——因此，RoutedUICommand是否可以运行将由CmdBinding的CanExecute事件决定。
        /// ——而且，RoutedUICommand的执行也是通过CmdBinding的Execute事件来进行的。
        /// </summary>
        public static CommandBinding CmdBinding
        {
            get { return cmdBinding; }
        }

        private static RoutedUICommand routedUICmd;
        /// <summary>
        /// [只读静态属性]表示在WPF系统中注册的一个RoutedUICommand。
        /// ——必须和CommandBinding配合才能使用。
        ///     CommandBinding要添加到主窗口的CommandBindings集合中；
        ///     RoutedUICommand则要向WPF系统注册。
        ///     
        /// ★说明：使用静态属性是因为这样在Xaml代码中比较便于绑定。
        /// </summary>
        public static RoutedUICommand RoutedUICmd
        {
            get { return routedUICmd; }
        }

        #endregion

        #region 方法=========================================================================================================

        static void cmdBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            //★⑧，修改此方法的实现。

            //考虑到性能问题，全部取消此判断。反正执行时会判断。
            //if (Globals.MainWindow == null) { e.CanExecute = false; return; }

            //EditorManager manager = Globals.MainWindow.EditorManager;
            //if (manager == null) { e.CanExecute = false; return; }

            //PageEditor pageEditor = manager.GetMainSelectedPageEditor();
            //if (pageEditor == null) { e.CanExecute = false; return; }

            //List<Widgets.Widget> selectedWidgets = pageEditor.GetSelectedWidgetsList(true);
            //if (selectedWidgets.Count < 1) { e.CanExecute = false; return; }

            e.CanExecute = true; return;
        }

        static void cmdBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            //★⑦，修改此方法的实现。
            LunarMessage.Warning(Execute());
        }

        /// <summary>
        /// [公开静态方法]即使此命令处于禁用状态，也可以通过代码调用此方法来执行特定任务！！！
        /// 
        /// 当被绑定的命令被调用（触发）时，会引发cmdBinding_Executed事件。
        /// 在cmdBinding_Executed事件处理器方法中已添加了调用Execute()方法的代码。
        /// 
        /// ——因此，触发命令，就相当于调用此方法！！！
        /// </summary>
        public static string Execute()
        {
            if (Globals.MainWindow == null) return "　　未找到Globals.MainWindow。";

            EditorManager manager = Globals.MainWindow.EditorManager;
            if (manager == null) return "　　未找到页面管理器。";

            PageEditor pageEditor = manager.GetMainSelectedPageEditor();
            if (pageEditor == null) return "　　未找到活动页面。";

            Widgets.StraitLineWidget straitLine = null;
            Widgets.Widget mainWidget = pageEditor.GetMainSelectedWidget();
            if (mainWidget != null)
            {
                straitLine = mainWidget as Widgets.StraitLineWidget;
                if (straitLine != null && straitLine.IsLinked)
                {
                    return "　　不能相对于连接线执行“对齐”操作！";
                }
            }

            List<Widgets.Widget> selectedWidgets = pageEditor.GetSelectedWidgetsList(true);

            //挂接的线不进行对齐操作。
            for (int i = selectedWidgets.Count - 1; i >= 0; i--)
            {
                StraitLineWidget sw = selectedWidgets[i] as StraitLineWidget;
                if (sw == null) continue;

                if (sw.IsLinked) { selectedWidgets.Remove(sw); }
            }

            if (selectedWidgets.Count < 1) return "　　未选定部件。";
            else if (selectedWidgets.Count == 1)
            {
                Widgets.StraitLineWidget sw = selectedWidgets[0] as Widgets.StraitLineWidget;
                if (sw != null && sw.IsLinked)
                {
                    return "　　连接线不能执行“对齐”操作！它是自动定位的。";
                }

                AlignToPageLeftSide(manager, pageEditor, selectedWidgets);
                return string.Empty;
            }

            ModifingInfo info = new ModifingInfo() { ModifingDescription = "部件左对齐" };
            manager.GetSelectedPageEditorStatus(info);
            manager.GetSelectedWidgetStatus_Old(info);
            manager.GetSelectedWidgetStatus_New(info);

            ModifingItem<Action, ModifingInfo> mi = new ModifingItem<Action, ModifingInfo>(info);

            double left = 0;

            Widgets.Widget baseWidget = null;

            if (mainWidget != null)
            {
                baseWidget = mainWidget;
                left = mainWidget.TopLeft.X;
            }
            else
            {
                baseWidget = selectedWidgets[0];
                left = baseWidget.TopLeft.X;
            }

            //以防万一，再验证一次。
            if (straitLine != null && straitLine.IsLinked)
            {
                return "　　不能相对于连接线执行“对齐”操作！";
            }

            List<ILinkableLine> linkedLines = pageEditor.GetLinkedLines(selectedWidgets);

            foreach (Widgets.Widget w in selectedWidgets)
            {
                if (w == baseWidget) continue;
                w.MoveLeftSiderTo(mi, left);
            }

            //刷新挂接的直线的位置
            pageEditor.RefreshLinkedLines(mi, linkedLines);

            manager.RegisterModifingItem(mi);

            return string.Empty;
        }

        /// <summary>
        /// ★要保证widget参数不是连接线。
        /// 
        /// 单个部件左齐是指对齐到页面左侧边30这个位置。
        /// </summary>
        private static void AlignToPageLeftSide(EditorManager manager, PageEditor pageEditor, List<Widget> selectedWidgets)
        {
            if (manager == null || pageEditor == null ||
                selectedWidgets == null || selectedWidgets.Count != 1) return;

            Widget widget = selectedWidgets[0];

            ModifingInfo info = new ModifingInfo() { ModifingDescription = "部件左对齐" };
            manager.GetSelectedPageEditorStatus(info);
            manager.GetSelectedWidgetStatus_Old(info);
            manager.GetSelectedWidgetStatus_New(info);

            ModifingItem<Action, ModifingInfo> mi = new ModifingItem<Action, ModifingInfo>(info);

            widget.MoveLeftSiderTo(mi, pageEditor.EditArea.Left);

            List<ILinkableLine> linkedLines = pageEditor.GetLinkedLines(selectedWidgets);
            pageEditor.RefreshLinkedLines(mi, linkedLines);

            manager.RegisterModifingItem(mi);
        }

        #endregion
    }
}
